package base;

import static util.Constant.STR_INVALID_ID;

import java.util.HashSet;

/**
 * The Event {@code class}. Create Event object with an ID, a name and a list of
 * Tag.
 * 
 * @author Peter NGO, Guillaume POUSSEL and Mathieu RUL
 * 
 * @version 1.0
 */
public class Event {

	/**
	 * The list of tag ID
	 */
	private HashSet<Integer> tags;

	/**
	 * The event name
	 */
	private String name;

	/**
	 * The event ID
	 */
	private Integer ID;

	/**
	 * Constructor of the {@code class}. Create a Event.
	 */
	public Event() {
		this("Unnamed Event");
	}

	/**
	 * Constructor of the {@code class}. Create a Event from an ID.
	 * 
	 * @param ID
	 *            the event ID.
	 * 
	 * @throws IllegalArgumentException
	 */
	public Event(Integer ID) throws IllegalArgumentException {
		if (ID < 0)
			throw new IllegalArgumentException(STR_INVALID_ID);

		this.ID = ID;
	}

	/**
	 * Constructor of the {@code class}. Create a tag from parameter.
	 * 
	 * @param ID
	 *            the Tag ID
	 * 
	 * @param name
	 *            the Tag name
	 * 
	 * @param tags
	 *            the list of Tag.
	 * 
	 * @throws IllegalArgumentException
	 */
	public Event(Integer ID, String name, HashSet<Integer> tags)
			throws IllegalArgumentException {
		if (ID < 0)
			throw new IllegalArgumentException(STR_INVALID_ID);

		this.ID = ID;
		this.name = name;
		this.tags = tags;
	}

	/**
	 * Constructor of the {@code class}. Create a Event from a name.
	 * 
	 * @param name
	 *            the event name.
	 */
	public Event(String name) {
		this(name, new HashSet<Integer>());
	}

	/**
	 * Constructor of the {@code class}. Create a Event from a name and a list
	 * of Tag.
	 * 
	 * @param name
	 *            the event name.
	 * 
	 * @param tags
	 *            the list of Tag.
	 */
	public Event(String name, HashSet<Integer> tags) {
		this(0, name, tags);
	}

	/**
	 * Add a Tag to this Event
	 * 
	 * @param ID
	 *            The ID of the Tag to add
	 */
	public boolean add(Integer ID) {
		return tags.add(ID);
	}

	/**
	 * Add a Tag to this Event
	 * 
	 * @param tag
	 *            The Tag to add
	 */
	public boolean add(Tag tag) {
		return tags.add(tag.getID());
	}

	/**
	 * Clear the Event
	 */
	public void clear() {
		tags.clear();
	}

	/**
	 * Verify if this Event contains a Tag
	 * 
	 * @param tag
	 *            The Tag to check
	 * 
	 * @return {@code true} if the Event contains the Tag; {@code false}
	 *         otherwise.
	 */
	public boolean contains(Tag tag) {
		return tags.contains(tag.getID());
	}

	/**
	 * Check equality between two events.
	 * 
	 * If this method get an Event, it compares the two IDs, else it returns
	 * false.
	 * 
	 * @param object
	 *            Another object to compare
	 * 
	 * @return {@code true} if the parameter are an Event; {@code false}
	 *         otherwise.
	 */
	public boolean equals(Object object) {
		return (object instanceof Event && ((Event) object).getID() == this.ID);
	}

	/**
	 * Get the Event ID
	 * 
	 * @return The Event ID
	 */
	public int getID() {
		return this.ID;
	}

	/**
	 * Get the event name
	 * 
	 * @return The event name
	 */
	public String getName() {
		return name;
	}

	/**
	 * Get the Tag ID list
	 * 
	 * @return The Tag ID list
	 */
	public HashSet<Integer> getTags() {
		return tags;
	}

	/**
	 * Get an hash representation of the Event
	 * 
	 * @return the hash representation of the Event
	 */
	@Override
	public int hashCode() {
		return name.hashCode();
	}

	/**
	 * Verify if this Event has a Tag
	 * 
	 * @return {@code true} if the Event contains a Tag; {@code false}
	 *         otherwise.
	 */
	public boolean isEmpty() {
		return tags.isEmpty();
	}

	/**
	 * Remove a Tag from this Event
	 * 
	 * @param ID
	 *            The ID of the Tag to remove
	 */
	public boolean remove(Integer ID) {
		return tags.remove(ID);
	}

	/**
	 * Remove a Tag from this Event
	 * 
	 * @param tag
	 *            The Tag to remove
	 */
	public boolean remove(Tag tag) {
		return tags.remove(new Integer(tag.getID()));
	}

	/**
	 * Set the event name
	 * 
	 * @param eventName
	 *            The event name
	 */
	public void setName(String eventName) {
		name = eventName;
	}

	/**
	 * Set the Tag ID list
	 * 
	 * @param tags
	 *            the Tags to set
	 */
	public void setTags(HashSet<Integer> tags) {
		this.tags = tags;
	}

	/**
	 * Returns a {@code String} object representing the Event's value.
	 * 
	 * @return a string representation of the Event.
	 */
	@Override
	public String toString() {
		String retour = "Event " + ID + " (" + name + ")";
		if (!tags.isEmpty())
			retour += " :\n";
		for (Integer tagID : tags) {
			retour += "  * Tag n°" + tagID + "\n";
		}
		return retour;
	}
}